using System;
using System.Collections;
using System.Text;

namespace Qiang.Topology.Geometries
{
    /// <summary>
    /// Basic implementation of <c>MultiPolygon</c>.
    /// </summary>
    public class MultiPolygon : GeometryCollection ,IMultiPolygon
    {
        /// <summary>
        /// Represents an empty <c>MultiPolygon</c>.
        /// </summary>
        public static new readonly IMultiPolygon Empty = new GeometryFactory().CreateMultiPolygon(null);

        /// <summary>
        /// Constructs a <c>MultiPolygon</c>.
        /// </summary>
        /// <param name="polygons">
        /// The <c>Polygon</c>s for this <c>MultiPolygon</c>
        /// , or <c>null</c> or an empty array to create the empty point.
        /// Elements may be empty <c>Polygon</c>s, but not <c>null</c>
        /// s. The polygons must conform to the assertions specified in the <A
        /// HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
        /// Specification for SQL</A> .
        /// </param>
        /// <param name="precisionModel">
        /// The specification of the grid of allowable points
        /// for this <c>MultiPolygon</c>.
        /// </param>
        /// <param name="SRID">
        /// The ID of the Spatial Reference System used by this
        /// <c>MultiPolygon</c>.
        /// </param>
        /// <deprecated> 
        /// Use GeometryFactory instead. 
        /// </deprecated>
        [Obsolete("Use GeometryFactory instead")]
        public MultiPolygon(Polygon[] polygons, PrecisionModel precisionModel, int SRID) 
            : this(polygons, new GeometryFactory(precisionModel, SRID, DefaultCoordinateSequenceFactory.Instance)) { }

        /// <param name="polygons">
        /// The <c>Polygon</c>s for this <c>MultiPolygon</c>,
        /// or <c>null</c> or an empty array to create the empty
        /// point. Elements may be empty <c>Polygon</c>s, but
        /// not <c>null</c>s. The polygons must conform to the
        /// assertions specified in the <A
        /// HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple
        /// Features Specification for SQL</A>.
        /// </param>
        public MultiPolygon(IPolygon[] polygons, GeometryFactory factory) 
            : base(polygons, factory) { }  

        public override Dimensions Dimension
        {
            get
            {
                return Dimensions.Surface;
            }
        }

        public override Dimensions BoundaryDimension
        {
            get
            {
                return Dimensions.Curve;
            }
        }

        [Obsolete("Use reflection! GetType().FullName")]
        public override string GeometryType
        {
            get
            {
                return "MultiPolygon";
            }
        }

        public override bool IsSimple
        {
            get
            {
                return true;
            }
        }

        public override IGeometry Boundary
        {
            get
            {
                if (IsEmpty) return Factory.CreateGeometryCollection(null);
                ArrayList allRings = new ArrayList();
                for (int i = 0; i < geometries.Length; i++)
                {
                    Polygon polygon = (Polygon)geometries[i];
                    GeometryCollection rings = (GeometryCollection)polygon.Boundary;
                    for (int j = 0; j < rings.NumGeometries; j++)
                        allRings.Add(rings.GetGeometryN(j));                    
                }
                LineString[] allRingsArray = new LineString[allRings.Count];
                return Factory.CreateMultiLineString((LineString[])allRings.ToArray(typeof(LineString)));
            }
        }

        public override bool EqualsExact(IGeometry other, double tolerance) 
        {
            if (!IsEquivalentClass(other)) 
                return false;
            return base.EqualsExact(other, tolerance);
        }
    }
}
